package com.qd.panda.service.card.collect;

import com.cdqidi.constant.ConstantDto;
import com.cdqidi.core.weixinmanager.model.MiddleUser;
import com.cdqidi.core.weixinmanager.service.MiddleUserService;
import com.cdqidi.exception.ApiException;
import com.qd.common.panda.config.PandaParkConfigDTO;
import com.qd.common.panda.domain.entity.card.collect.CollectCardDTO;
import com.qd.common.panda.domain.entity.card.collect.ReceiveCardDTO;
import com.qd.common.panda.domain.entity.card.collect.ReceiveCardsDTO;
import com.qd.common.sys.util.SecurityUtils;
import com.qd.panda.model.CardInfo;
import com.qd.panda.model.CardPlan;
import com.qd.panda.model.CollectCard;
import com.qd.panda.service.card.CardInfoService;
import com.qd.panda.service.card.CardPlanService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;

/**
 * 〈一句话功能简述〉<br>
 *
 * @author sjk
 * @create 2023-09-22 14:26
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ReceiveCardService {

    private final CollectCardHolderService collectCardHolderService;
    private final CollectCardService collectCardService;
    private final CardInfoService cardInfoService;
    private final CardPlanService cardPlanService;
    private final MiddleUserService middleUserService;
    private final PandaParkConfigDTO pandaParkConfig;


    @Transactional(rollbackFor = Exception.class)
    public void receiveCards(String userId, String mobile, ReceiveCardsDTO receiveCardsDTO) {
        CollectCardDTO collectCardDTO = collectCardHolderService.check(receiveCardsDTO.getCid(), receiveCardsDTO.getPromotionCode());
        if (collectCardDTO.getAvailableQuantity() != -1 && collectCardDTO.getAllocatedQuantity() != -1) {
            if (collectCardDTO.getAvailableQuantity() < 1) {
                throw new ApiException(10005, "券已发放完，下次再来哟！");
            }
        }
        List<CardInfo> list = cardInfoService.getListByPlanId(collectCardDTO.getPlanId());
        if (list.isEmpty()) {
            throw new ApiException(10005, "券已发放完，下次再来哟！");
        }
        LocalDate currentDate = LocalDate.now();
        if (collectCardHolderService.existsCollectCard(receiveCardsDTO.getPromotionCode(), receiveCardsDTO.getCid(), currentDate)) {
            throw new ApiException("请勿重复领取");
        }
        if (collectCardDTO.getAvailableQuantity() == -1 && collectCardDTO.getAllocatedQuantity() == -1) {
            //需要批量领券的时候,看是否需要回赠
            CardPlan cardPlan = cardPlanService.getById(collectCardDTO.getPlanId());
            if (null == cardPlan) {
                receiveCardsDTO.setPromoterId(null);
            } else {
                if (StringUtils.hasLength(cardPlan.getRebate())) {
                    if (cardPlan.getRebate().equals(ConstantDto.SF0)) {
                        receiveCardsDTO.setPromoterId(null);
                    }
                    if (SecurityUtils.getLoginUser().getUserId().equals(receiveCardsDTO.getPromoterId())) {
                        //领券人如果和分享人是一个人，那么也不赠送券
                        receiveCardsDTO.setPromoterId(null);
                    }
                } else {
                    receiveCardsDTO.setPromoterId(null);
                }
            }
            //promoterId有值的情况下，判断是否需要回赠，如果不需要就设置成空
            //后面只要判断到有值的情况下就直接分享
        } else {
            receiveCardsDTO.setPromoterId(null);
        }
        MiddleUser middleUser = null;
        if (StringUtils.hasLength(receiveCardsDTO.getPromoterId())) {
            middleUser = middleUserService.getUniqueByUserIdAndAppId(receiveCardsDTO.getPromoterId(), pandaParkConfig.getDefaultMiniProgramAppId());
            if (null == middleUser) {
                log.error("获取分享人信息失败,userId: {},小程序ID: {}", receiveCardsDTO.getPromoterId(), pandaParkConfig.getDefaultMiniProgramAppId());
            }
        }
        for (CardInfo cardInfo : list) {
            if (currentDate.isBefore(cardInfo.getUseStartTime())) {
                throw new ApiException("请在[" + cardInfo.getUseStartTime().toString() + "]开始兑换");
            }
            if (currentDate.isAfter(cardInfo.getUseEndTime())) {
                throw new ApiException("超过规定兑换时间，不能兑换");
            }
            for (int i = 0; i < cardInfo.getCardQuantity(); i++) {
                //劵有几张就领几次
                ReceiveCardDTO dto = new ReceiveCardDTO();
                dto.setPlanId(cardInfo.getPlanId());
                dto.setCardMsgId(cardInfo.getCardMsgId());
                if (collectCardDTO.getAvailableQuantity() == -1 && collectCardDTO.getAllocatedQuantity() == -1) {
                    //自动领券
                    collectCardService.automatic(userId, mobile, dto, middleUser);
                } else {
                    collectCardService.buildCardInfoDetail(userId, mobile, dto);
                }

                dto.freeData();
            }
            cardInfo.freeData();
        }
        if (StringUtils.hasLength(receiveCardsDTO.getPromoterId()) && null != middleUser) {
            log.info("发送小程序模板消息");
            collectCardService.sendTemplateMessage(receiveCardsDTO.getCid(), receiveCardsDTO.getPromoterId());
        }
        list.clear();
        if (collectCardDTO.getAvailableQuantity() != -1 && collectCardDTO.getAllocatedQuantity() != -1) {
            //不是无限量券需要更新券的使用数量
            collectCardDTO.setAvailableQuantity(collectCardDTO.getAvailableQuantity() - 1);
            collectCardDTO.setQrCode(null);
            CollectCard collectCard = collectCardService.dtoToModel(collectCardDTO);
            try {
                collectCardService.updateById(collectCard);
            } finally {
                collectCardService.clearCache(collectCard);
                collectCard.freeData();
            }
        }

        collectCardDTO.freeData();
    }


}